package com.tanhua.server.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.common.service.PicUploadService;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.common.vo.ErrorResult;
import com.tanhua.common.vo.PicUploadResult;
import com.tanhua.dubbo.api.QuanZiApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VideoApi;
import com.tanhua.dubbo.pojo.Comment;
import com.tanhua.dubbo.pojo.UserInfo;
import com.tanhua.dubbo.pojo.Video;
import com.tanhua.dubbo.vo.PageInfo;
import com.tanhua.server.config.DefaultRecommendVideoConfig;
import com.tanhua.server.config.TanhuaConfig;
import com.tanhua.server.vo.CommentVo;
import com.tanhua.server.vo.PageResult;
import com.tanhua.server.vo.VideoVo;
import lombok.extern.slf4j.Slf4j;

import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class VideoService {

    @DubboReference(version = "1.0.0")
    private VideoApi videoApi;

    @DubboReference(version = "1.0.0")
    private QuanZiApi quanZiApi;

    @DubboReference(version = "1.0.0")
    private UserInfoApi userInfoApi;

    @Autowired
    private VideoMQService videoMQService;

    @Autowired
    protected FastFileStorageClient storageClient;

    @Autowired
    private FdfsWebServer fdfsWebServer;

    @Autowired
    private PicUploadService picUploadService;

    @Autowired
    private DefaultRecommendVideoConfig defaultRecommendVideoConfig;

    public Object saveVideo(MultipartFile picFile, MultipartFile videoFile) {
        try {
            Video video = new Video();

            video.setUserId(UserThreadLocal.get());

            //上传图片
            PicUploadResult uploadResult = this.picUploadService.upload(picFile);
            video.setPicUrl(uploadResult.getName());

            //上传小视频
            StorePath storePath = this.storageClient
                    .uploadFile(videoFile.getInputStream(), videoFile.getSize(),
                            StrUtil.subAfter(videoFile.getOriginalFilename(), '.', true), null);

            video.setVideoUrl(fdfsWebServer.getWebServerUrl() + storePath.getFullPath());
            String videoId = this.videoApi.saveVideo(video);

            //发消息
            this.videoMQService.videoMsg(videoId);

            return videoId;
        } catch (Exception e) {
            String msg = StrUtil.format("上传小视频失败！ videoFile = {}, picFile = {}"
                    , videoFile.getOriginalFilename(), picFile.getOriginalFilename());
            log.error(msg, e);
        }
        return ErrorResult.builder().errCode("500").errMessage("上传小视频失败！").build();
    }

    /**
     * 查询小视频列表
     *
     * @param page
     * @param pageSize
     * @return
     */
    public PageResult queryVideoList(int page, Integer pageSize) {
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);

        Long userId = UserThreadLocal.get();
        PageInfo<Video> pageInfo = this.videoApi.queryVideoList(userId, page, pageSize);
        List<Video> videoList = pageInfo.getRecords();
        //推荐的小视频列表
        ArrayList<VideoVo> videoVoList = new ArrayList<>();

        if (CollUtil.isEmpty(videoList)) {
            //TODO 没有数据，返回默认的小视频数据
            List<String> userIdList = this.defaultRecommendVideoConfig.getVideos();
            for (String uid : userIdList) {
                Video video = this.videoApi.queryVideoById(uid);
                VideoVo videoVo = BeanUtil.toBeanIgnoreError(video, VideoVo.class);
                videoVo.setUserId(video.getUserId());
                videoVo.setCover(video.getPicUrl());
                videoVo.setVideoUrl(video.getVideoUrl());
                videoVo.setId(video.getId().toHexString());
                videoVo.setSignature("黑马程序员");
                videoVo.setCommentCount(this.videoApi.queryCommentCount(video.getId()));
                videoVo.setHasFocus(this.videoApi.queryUserIsFocus(userId, video.getUserId()) ? 1 : 0);//是否关注
                videoVo.setHasLiked(this.quanZiApi.queryUserIsLike(userId, videoVo.getId()) ? 1 : 0);
                videoVo.setLikeCount(Convert.toInt(this.quanZiApi.queryLikeCount(videoVo.getId())));
                videoVoList.add(videoVo);
            }
            return pageResult;
        }

        List<Object> userIdList = CollUtil.getFieldValues(videoList, "userId");
        List<UserInfo> userInfoList = this.userInfoApi.queryByUserIdList(userIdList);

        for (Video video : videoList) {
            VideoVo videoVo = BeanUtil.toBeanIgnoreError(video, VideoVo.class);
            for (UserInfo userInfo : userInfoList) {
                if (ObjectUtil.equal(video.getUserId(), userInfo.getUserId())) {
                    //拷贝值，主要拷贝头像和昵称
                    BeanUtil.copyProperties(userInfo, videoVo, "id");
                    break;
                }
            }
            videoVo.setLikeCount(Convert.toInt(this.videoApi.queryLikeCount(video.getId().toHexString())));
            videoVo.setHasLiked(Convert.toInt(this.videoApi.queryUserIsLike(userId, video.getId().toHexString())));
            videoVo.setHasFocus(this.videoApi.queryUserIsFocus(userId, video.getUserId()) ? 1 : 0);
            videoVo.setCommentCount(this.videoApi.queryCommentCount(video.getId()));
            videoVoList.add(videoVo);
        }

        pageResult.setItems(videoVoList);
        return pageResult;
    }

    public Object likeVideo(String vedioId) {
        Long userId = UserThreadLocal.get();
        Boolean result = this.quanZiApi.likeComment(userId, vedioId);
        if (!result) {
            return ErrorResult.builder().errCode("500").errMessage("点赞失败").build();
        }
        return null;
    }

    public Object disLikeVideo(String vedioId) {
        Long userId = UserThreadLocal.get();
        Boolean result = this.quanZiApi.disLikeComment(userId, vedioId);
        if (!result) {
            return ErrorResult.builder().errCode("500").errMessage("点赞失败").build();
        }
        return null;
    }

    public PageResult getCommentList(String videoId, String page, String pageSize) {
        PageResult pageResult = new PageResult();
        pageResult.setPage(Convert.toInt(page));
        pageResult.setPagesize(Convert.toInt(pageSize));
        pageResult.setCounts(this.videoApi.queryCommentCount(new ObjectId(videoId)));

        PageInfo<Comment> pageInfo = this.quanZiApi.queryCommentList(videoId, Convert.toInt(page), Convert.toInt(pageSize));
        if (ObjectUtil.isEmpty(pageInfo.getRecords())) {
            return pageResult;
        }

        List<CommentVo> commentVoList = new ArrayList<>();
        List<Comment> comments = pageInfo.getRecords();
        for (Comment comment : comments) {
            CommentVo commentVo = new CommentVo();
            commentVo.setId(comment.getId().toHexString());
            Long userId = comment.getUserId();
            UserInfo userInfo = this.userInfoApi.queryByUserId(userId);
            commentVo.setAvatar(userInfo.getLogo());
            commentVo.setNickname(userInfo.getNickName());
            commentVo.setContent(comment.getContent());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            commentVo.setCreateDate(sdf.format(new Date(comment.getCreated())));

            Long likeCount = this.videoApi.queryLikeCount(Convert.toStr(comment.getId()));
            if (ObjectUtil.isEmpty(likeCount)) {
                commentVo.setLikeCount(0);
            } else {
                commentVo.setLikeCount(Convert.toInt(likeCount));
            }

            Boolean isLike = this.quanZiApi.queryUserIsLike(UserThreadLocal.get(), commentVo.getId());
            if (ObjectUtil.isEmpty(isLike) || ObjectUtil.equal(isLike, false)) {
                commentVo.setHasLiked(0);
            } else {
                commentVo.setHasLiked(1);
            }
            commentVoList.add(commentVo);
        }

        pageResult.setItems(commentVoList);

        return pageResult;
    }

    public Boolean saveComment(String videoId, String comment) {
        Long userId = UserThreadLocal.get();
        Boolean isSuccess = this.quanZiApi.saveComment(userId, videoId, comment);
        return isSuccess;
    }

    public Object userFocus(String uid) {
        Long userId = UserThreadLocal.get();
        Boolean result = this.videoApi.userFocus(Convert.toStr(userId), uid);
        if (ObjectUtil.isEmpty(result)) {
            return ErrorResult.builder().errCode("500").errMessage("关注失败").build();
        }
        return result;
    }

    public Object userUnFocus(String uid) {
        try {
            Long userId = UserThreadLocal.get();
            this.videoApi.userUnFocus(Convert.toStr(userId), uid);
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return ErrorResult.builder().errCode("500").errMessage("取消关注失败").build();
        }
    }
}
